package com.wangxiaonan.wxwork.domain;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.triggers.AbstractTrigger;
import org.quartz.impl.triggers.CronTriggerImpl;

import java.io.Serializable;
import java.text.ParseException;
import java.util.Date;

public class ScheduleJob extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 8784257712308955606L;
    public static final int STATUS_VALID = 1;
    public static final int STATUS_INVALID = 0;

    public static final int TYPE_CRON = 1;
    public static final int TYPE_SIMPLE = 2;

    /**
     *
     */
    private Integer id;

    /**
     * 任务名称
     */
    private String name;

    /**
     * 任务组
     */
    private String group;

    /**
     * 任务执行类
     */
    private String clazz;

    /**
     * 任务描述
     */
    private String description;

    /**
     * cron表达式
     */
    private String cronExpression;

    /**
     * 表达式类型(1:cron,2:simple)
     */
    private Integer type;

    /**
     * 使用状态(1:启用,0:禁用)
     */
    private Integer status;

    /**
     * 开始时间
     */
    private Date startDate;

    /**
     * 结束时间
     */
    private Date endDate;

    /**
     * 首次延迟时间(毫秒)
     */
    private Long startDelay;

    /**
     * 任务数据
     */
    private String data;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getCronExpression() {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Long getStartDelay() {
        return startDelay;
    }

    public void setStartDelay(Long startDelay) {
        this.startDelay = startDelay;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    @SuppressWarnings("unchecked")
    public JobDetail getJobDetail() throws ClassNotFoundException {
        JobBuilder builder = JobBuilder.newJob((Class<? extends Job>) Class.forName(getClazz()))
                .withIdentity(getJobKey());
        if (StringUtils.isNotBlank(getDescription())) {
            builder.withDescription(getDescription());
        }
        if (StringUtils.isNotBlank(getData())) {
            JSONObject jobData = JSONObject.parseObject(getData());
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.putAll(jobData.getInnerMap());
            builder.usingJobData(jobDataMap);
        }
        return builder.build();
    }

    public Trigger getTrigger() throws ParseException {
        AbstractTrigger<?> trigger;
        if (TYPE_CRON == getType()) {
            CronTriggerImpl cronTrigger = new CronTriggerImpl();
            if (StringUtils.isBlank(getCronExpression())) {
                throw new NullPointerException("cron expression is null");
            }
            cronTrigger.setCronExpression(getCronExpression());
            trigger = cronTrigger;
        } else {
            throw new IllegalArgumentException("not support simple trigger type");
        }
        trigger.setKey(getTriggerKey());
        if (getStartDate() != null) {
            trigger.setStartTime(getStartDate());
        } else if (getStartDelay() != null) {
            trigger.setStartTime(new Date(System.currentTimeMillis() + getStartDelay()));
        }
        if (getEndDate() != null) {
            trigger.setEndTime(getEndDate());
        }
        return trigger;
    }

    public TriggerKey getTriggerKey() {
        TriggerKey triggerKey;
        if (StringUtils.isNotBlank(getName())) {
            triggerKey = new TriggerKey(getName(), getGroup());
        } else {
            triggerKey = new TriggerKey("Trigger-" + getId(), getGroup());
        }
        return triggerKey;
    }

    public JobKey getJobKey() {
        JobKey jobKey;
        if (StringUtils.isNotBlank(getName())) {
            jobKey = new JobKey("Job-" + getName() + "-" + getId(), getGroup());
        } else {
            jobKey = new JobKey("Job-" + getId(), getGroup());
        }
        return jobKey;
    }

    public boolean isValid() {
        if (STATUS_INVALID == getStatus()) {
            return false;
        } else if (StringUtils.isBlank(getCronExpression())) {
            return false;
        } else if (getId() == null) {
            return false;
        } else {
            return true;
        }
    }
}